﻿namespace UnityEditor
{
    using System;
    using UnityEngine;

    internal class AssetStoreWindow : EditorWindow, ICanHazCustomMenu
    {
        private AssetStoreContext contextScriptObject;
        private int currentSkin;
        private bool isDocked;
        private bool isOffline;
        private MouseCursor m_SavedCursor;
        private int m_SavedCursorCountHack;
        private Vector2 minDockedSize;
        private Vector2 minUndockedSize;
        private WebView webView;

        private AssetStoreWindow()
        {
            Resolution currentResolution = Screen.currentResolution;
            int num = (currentResolution.width < 0x400) ? currentResolution.width : 0x400;
            int num2 = (currentResolution.height < 0x380) ? (currentResolution.height - 0x60) : 800;
            int num3 = (currentResolution.width - num) / 2;
            int num4 = (currentResolution.height - num2) / 2;
            base.position = new Rect((float) num3, (float) num4, (float) num, (float) num2);
        }

        public virtual void AddItemsToMenu(GenericMenu menu)
        {
            menu.AddItem(new GUIContent("Reload"), false, new GenericMenu.MenuFunction(this.Reload));
        }

        private void CreateContextObject()
        {
            if (this.contextScriptObject == null)
            {
                this.contextScriptObject = ScriptableObject.CreateInstance<AssetStoreContext>();
                this.contextScriptObject.hideFlags = HideFlags.HideAndDontSave;
                this.contextScriptObject.window = this;
            }
        }

        public static AssetStoreWindow Init()
        {
            AssetStoreWindow window = EditorWindow.GetWindow<AssetStoreWindow>();
            Resolution currentResolution = Screen.currentResolution;
            int num = (currentResolution.width < 0x400) ? currentResolution.width : 0x400;
            int num2 = (currentResolution.height < 0x380) ? (currentResolution.height - 0x60) : 800;
            window.minUndockedSize = new Vector2((float) num, (float) num2);
            window.minDockedSize = new Vector2(512f, 256f);
            window.minSize = !window.docked ? window.minUndockedSize : window.minDockedSize;
            window.maxSize = new Vector2(2048f, 2048f);
            window.Show();
            window.m_SavedCursor = MouseCursor.Arrow;
            return window;
        }

        private void InitWebView()
        {
            this.currentSkin = EditorGUIUtility.skinIndex;
            this.isDocked = base.docked;
            this.isOffline = false;
            if (this.webView == null)
            {
                this.webView = ScriptableObject.CreateInstance<WebView>();
                this.webView.InitWebView((int) base.position.width, (int) base.position.height, false);
                this.webView.hideFlags = HideFlags.HideAndDontSave;
                this.webView.LoadFile(AssetStoreUtils.GetLoaderPath());
            }
            else
            {
                this.webView.LoadFile(AssetStoreUtils.GetLoaderPath());
            }
            this.webView.SetDelegateObject(this);
            base.wantsMouseMove = true;
        }

        private void InvokeJSMethod(string objectName, string name, params object[] args)
        {
            if (this.webView != null)
            {
                WebScriptObject obj2 = this.webView.windowScriptObject.Get(objectName);
                if (obj2 != null)
                {
                    obj2.InvokeMethodArray(name, args);
                }
            }
        }

        public void Logout()
        {
            this.InvokeJSMethod("document.AssetStore.login", "logout", new object[0]);
        }

        public void OnDestroy()
        {
            UnityEngine.Object.DestroyImmediate(this.webView);
            if (this.contextScriptObject != null)
            {
                this.contextScriptObject.window = null;
            }
        }

        public void OnDisable()
        {
            AssetStoreUtils.UnRegisterDownloadDelegate(this);
        }

        public void OnDownloadProgress(string id, string message, int bytes, int total)
        {
            object[] args = new object[] { id, message, bytes, total };
            this.InvokeJSMethod("document.AssetStore.pkgs", "OnDownloadProgress", args);
        }

        private void OnEnable()
        {
            AssetStoreUtils.RegisterDownloadDelegate(this);
        }

        private void OnFocus()
        {
            if (this.webView != null)
            {
                this.webView.Focus();
            }
        }

        private void OnGUI()
        {
            if (this.webView == null)
            {
                this.InitWebView();
            }
            EditorGUIUtility.AddCursorRect(new Rect(0f, 0f, base.position.width, base.position.height), this.m_SavedCursor);
            if (Event.current.type == EventType.Layout)
            {
                if ((this.webView != null) && (this.currentSkin != EditorGUIUtility.skinIndex))
                {
                    this.currentSkin = EditorGUIUtility.skinIndex;
                    this.InvokeJSMethod("document.AssetStore", "refreshSkinIndex", new object[0]);
                    base.Repaint();
                }
                this.UpdateDockStatusIfNeeded();
            }
            this.webView.DoGUI(new Rect(0f, 0f, base.position.width, base.position.height));
        }

        private void OnLoadError(string frameName)
        {
            if (this.webView != null)
            {
                if (this.isOffline)
                {
                    Debug.LogError("Unexpected error: Failed to load offline Asset Store page");
                }
                else
                {
                    this.isOffline = true;
                    this.webView.LoadFile(AssetStoreUtils.GetOfflinePath());
                }
            }
        }

        private void OnLostFocus()
        {
            if (this.webView != null)
            {
                this.webView.UnFocus();
            }
        }

        private void OnReceiveTitle(string iTitle, string frameName)
        {
            base.title = iTitle;
            this.SetContextObject();
        }

        private void OnWebViewDirty()
        {
            base.Repaint();
        }

        public static void OpenURL(string url)
        {
            AssetStoreWindow window = Init();
            object[] args = new object[] { url };
            window.InvokeJSMethod("document.AssetStore", "openURL", args);
            window.CreateContextObject();
            window.contextScriptObject.initialOpenURL = url;
        }

        public void Reload()
        {
            if (this.isOffline)
            {
                this.InitWebView();
            }
            else
            {
                this.currentSkin = EditorGUIUtility.skinIndex;
                this.isDocked = base.docked;
                object[] args = new object[] { true };
                this.InvokeJSMethod("location", "reload", args);
            }
        }

        private void SetContextObject()
        {
            this.CreateContextObject();
            this.contextScriptObject.docked = base.docked;
            this.webView.windowScriptObject.Set<AssetStoreContext>("context", this.contextScriptObject);
        }

        private void SetCursor(int cursor)
        {
            if (cursor != this.m_SavedCursor)
            {
                if ((cursor != 0) || (this.m_SavedCursorCountHack-- <= 0))
                {
                    this.m_SavedCursorCountHack = 1;
                    this.m_SavedCursor = (MouseCursor) cursor;
                    base.Repaint();
                }
            }
            else
            {
                this.m_SavedCursorCountHack = 1;
            }
        }

        private void UpdateDockStatusIfNeeded()
        {
            if (this.isDocked != base.docked)
            {
                base.minSize = !base.docked ? this.minUndockedSize : this.minDockedSize;
                this.isDocked = base.docked;
                if (this.contextScriptObject != null)
                {
                    this.contextScriptObject.docked = base.docked;
                    this.InvokeJSMethod("document.AssetStore", "updateDockStatus", new object[0]);
                }
                base.Repaint();
            }
        }

        internal WebScriptObject scriptObject
        {
            get
            {
                return this.webView.windowScriptObject;
            }
        }
    }
}

